package traffic

//
// FlowProcessor
// @Description: flow data processor interface
//
type FlowProcessor interface {
	//
	// Init
	// @Description: init processor
	//
	Init()
	//
	// Process
	// @Description: do process method
	// @param raw
	// @return []byte
	//
	Process(raw []byte) []byte
}

//
// ProcessorNode
// @Description: processor chain node
//
type ProcessorNode struct {
	Processor FlowProcessor
	Next      *ProcessorNode
	Last      *ProcessorNode
}

//
// FlowProcessors
// @Description: processors
//
type FlowProcessors struct {
	head *ProcessorNode
	tail *ProcessorNode
}

//
// NewFlowProcessor
// @Description:
// @return *FlowProcessors
//
func NewFlowProcessor() *FlowProcessors {
	return &FlowProcessors{}
}

//
// ProcessReverse
// @Description: start process data by using processor reversely
// @receiver fp
//
func (fp FlowProcessors) ProcessReverse(bytes []byte) []byte {
	current := fp.tail
	for current != nil {
		//do process
		bytes = current.Processor.Process(bytes)
		//move to last
		current = current.Last
	}
	return bytes
}

//
// ProcessPositive
// @Description: start process data by using processor positively
// @receiver fp
//
func (fp FlowProcessors) ProcessPositive(bytes []byte) []byte {
	current := fp.head
	for current != nil {
		//do process
		bytes = current.Processor.Process(bytes)
		//move to next
		current = current.Next
	}
	return bytes
}

//
// Register
// @Description: register for data processor
// @receiver fp
// @param processor
//
func (fp *FlowProcessors) Register(processor FlowProcessor) {
	processor.Init()
	node := &ProcessorNode{
		Processor: processor,
		Next:      nil,
		Last:      nil,
	}
	if fp.head == nil {
		fp.head = node
		fp.tail = node
	} else {
		fp.tail.Next = node
		node.Last = fp.tail
		fp.tail = node
	}
}
